package com.suncky.frame.base.adapter;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;

import androidx.annotation.Nullable;

import com.suncky.frame.base.adapter.holder.ExpandableViewHolder;

import java.util.ArrayList;
import java.util.List;

public abstract class ExpandableListAdapter<G,C> extends BaseExpandableListAdapter implements ExpandableViewHolder.ViewEventListener {

    protected final Context context;
    protected List<G> data;
    protected int groupPosition = -1;
    protected int childPosition = -1;
    protected final int groupItemLayoutId;
    protected final int childItemLayoutId;

    public ExpandableListAdapter(Context context, List<G> data) {
        this(context, data, 0, 0);
    }


    public ExpandableListAdapter(Context context, List<G> data, int groupItemLayoutId, int childItemLayoutId) {
        this.context = context;
        this.data = data;
        this.groupItemLayoutId = groupItemLayoutId;
        this.childItemLayoutId = childItemLayoutId;
    }

    public Context getContext() {
        return context;
    }

    public void setData(List<G> data) {
        this.data = data;
        notifyDataSetChanged();
    }

    public List<G> getData() {
        return data;
    }

    public void setPosition(int groupPosition) {
        this.groupPosition = groupPosition;
    }

    public void setPosition(int groupPosition, int childPosition) {
        this.groupPosition = groupPosition;
        this.childPosition = childPosition;
    }

    public int getGroupPosition() {
        return groupPosition;
    }

    public int getChildPosition() {
        return childPosition;
    }

    public G getGroupPositionItem() {
        return getGroup(groupPosition);
    }

    public C getGroupChildPositionItem() {
        return getChild(groupPosition, childPosition);
    }

    public void refresh(int groupPosition) {
        setPosition(groupPosition);
        notifyDataSetChanged();
    }

    public void refresh(int groupPosition,int childPosition) {
        setPosition(groupPosition, childPosition);
        notifyDataSetChanged();
    }

    public void addGroup(G group) {
        if (group == null) {
            return;
        }
        if (data == null) {
            data = new ArrayList<>();
        }
        data.add(group);
        notifyDataSetChanged();
    }

    public void addGroup(List<G> groups) {
        if (groups == null || groups.size() == 0) {
            return;
        }
        if (data == null) {
            data = new ArrayList<>();
        }
        data.addAll(groups);
        notifyDataSetChanged();
    }

    public void addChild(int groupPosition, C child) {
        if (child == null) {
            return;
        }
        G group= getGroup(groupPosition);
        if (group == null) {
            return;
        }
        List<C> children = getChildren(group);
        if (children == null) {
            return;
        }
        children.add(child);
        notifyDataSetChanged();
    }

    public void addChild(int groupPosition, List<C> children) {
        if (children == null || children.size() == 0) {
            return;
        }
        G group= getGroup(groupPosition);
        if (group == null) {
            return;
        }
        List<C> destChildren = getChildren(group);
        if (destChildren == null) {
            return;
        }
        destChildren.addAll(children);
        notifyDataSetChanged();
    }

    public void insertGroup(int position, G group) {
        if (group == null || position < 0 || position > getGroupCount()) {
            return;
        }
        if (data == null) {
            data = new ArrayList<>();
        }
        data.add(position, group);
        notifyDataSetChanged();
    }

    public void insertGroup(int position, List<G> groups) {
        if (position == 0 || position > getGroupCount() || groups == null || groups.size() == 0) {
            return;
        }
        if (data == null) {
            data = new ArrayList<>();
        }
        data.addAll(position, groups);
        notifyDataSetChanged();
    }

    public void insertChild(int groupPosition, int childPosition, C child) {
        if (child == null) {
            return;
        }
        G group = getGroup(groupPosition);
        if (group == null) {
            return;
        }
        List<C> children = getChildren(group);
        if (children == null || childPosition == 0 || childPosition > children.size()) {
            return;
        }
        children.add(childPosition,child);
        notifyDataSetChanged();
    }

    public void insertChild(int groupPosition, int childPosition, List<C> children) {
        if (children == null || children.size() == 0) {
            return;
        }
        G group= getGroup(groupPosition);
        if (group == null) {
            return;
        }
        List<C> destChildren = getChildren(group);
        if (destChildren == null || childPosition == 0 || childPosition > children.size()) {
            return;
        }
        destChildren.addAll(childPosition, children);
        notifyDataSetChanged();
    }

    public void remove(int groupPosition) {
        if (groupPosition < 0 || groupPosition >= getGroupCount()) {
            return;
        }
        data.remove(groupPosition);
    }

    public void remove(int groupPosition, int childPosition) {
        if (groupPosition < 0 || groupPosition >= getGroupCount() || childPosition < 0 || childPosition >= getChildrenCount(groupPosition)) {
            return;
        }
        G group = getGroup(groupPosition);
        if (group == null) {
            return;
        }
        List<C> destChildren = getChildren(group);
        if (destChildren == null) {
            return;
        }
        destChildren.remove(childPosition);
    }

    public void clearData() {
        if (data != null) {
            data.clear();
        }
        notifyDataSetChanged();
    }

    @Override
    public int getGroupCount() {
        if (data == null) {
            return 0;
        }
        return data.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        if (data == null || groupPosition < 0 || data.size() <= groupPosition) {
            return 0;
        }
        List<C> children = getChildren(data.get(groupPosition));
        if (children == null) {
            return 0;
        }
        return children.size();
    }

    @Nullable
    @Override
    public G getGroup(int groupPosition) {
        if (data == null || groupPosition < 0 || data.size() <= groupPosition) {
            return null;
        }
        return data.get(groupPosition);
    }

    @Nullable
    @Override
    public C getChild(int groupPosition, int childPosition) {
        G group = getGroup(groupPosition);
        if (group == null) {
            return null;
        }
        List<C> children = getChildren(data.get(groupPosition));
        if (children == null || childPosition < 0 || children.size() <= childPosition) {
            return null;
        }
        return children.get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return groupPosition * 10000L + childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        ExpandableViewHolder viewHolder = getGroupViewHolder(groupPosition, convertView, parent);
        convertGroup(viewHolder, getGroup(groupPosition), groupPosition);
        return viewHolder.getConvertView();
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ExpandableViewHolder viewHolder = getChildViewHolder(groupPosition,childPosition, convertView, parent);
        convertChild(viewHolder, getChild(groupPosition, childPosition), groupPosition, childPosition);
        return viewHolder.getConvertView();
    }


    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;//默认返回true,否则ExpandableListView的Child点击事件无效
    }

    @Nullable
    public abstract List<C> getChildren(G group);
    public abstract void convertGroup(ExpandableViewHolder holder,G groupItem,int groupPosition);
    public abstract void convertChild(ExpandableViewHolder holder,C childItem,int groupPosition,int childPosition);

    @Override
    public void onGroupViewClick(View v, int groupPosition) {

    }

    @Override
    public void onChildViewClick(View v, int groupPosition, int childPosition) {

    }

    protected ExpandableViewHolder getGroupViewHolder(int groupPosition, View convertView, ViewGroup parent) {
        return ExpandableViewHolder.getGroupViewHolder(context, convertView, parent, groupItemLayoutId, groupPosition, this);
    }

    protected ExpandableViewHolder getChildViewHolder(int groupPosition, int childPosition, View convertView, ViewGroup parent) {
        return ExpandableViewHolder.getChildViewHolder(context, convertView, parent, childItemLayoutId, groupPosition, childPosition, this);
    }
}
